﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.Runtime.InteropServices;
using System.Diagnostics;
using System.Threading;
using System.Security.Permissions;



namespace System.Collections.Generic.Sync
{

    public class SyncDictionaryProxty<TKey, TValue> : IDictionary<TKey, TValue>
    {
        private ReaderWriterLockSlim _lock = new ReaderWriterLockSlim();
        IDictionary<TKey, TValue> BaseDictionary { get; set; }
        private   ICollection<KeyValuePair<TKey, TValue>> BaseCollection
        {
            get
            { return (ICollection<KeyValuePair<TKey, TValue>>)BaseDictionary; }
           
        }
        public SyncDictionaryProxty(IDictionary<TKey, TValue> dictionary)
        {
            BaseDictionary = dictionary;
        }








        #region IDictionary<TKey,TValue> Members

        public void Add(TKey key, TValue value)
        {
            _lock.EnterWriteLock();
            BaseDictionary.Add(key, value);
            _lock.ExitWriteLock();
        }

        public bool ContainsKey(TKey key)
        {
             
            _lock.EnterReadLock();
            var rv = BaseDictionary .ContainsKey(key);
            _lock.ExitReadLock();
            return rv;
        }

        public ICollection<TKey> Keys
        {
            get
            {
                _lock.EnterReadLock();
                var rv = BaseDictionary.Keys.ToList();
                _lock.ExitReadLock();
                return rv;
            }
        }

        public bool Remove(TKey key)
        {
            _lock.EnterWriteLock();
            var rv = BaseDictionary.Remove(key);
            _lock.ExitWriteLock();
            return rv;
        }

        public bool TryGetValue(TKey key, out TValue value)
        {
            _lock.EnterReadLock();
            var rv = BaseDictionary.TryGetValue(key, out value);
            _lock.ExitReadLock();
            return rv;
        }

        public ICollection<TValue> Values
        {
            get
            {
                _lock.EnterReadLock();
                var rv = BaseDictionary.Values.ToList ();
                _lock.ExitReadLock();
                return rv;
            }
        }

        public TValue this[TKey key]
        {
            get
            {
                _lock.EnterReadLock();
                var rv = BaseDictionary[key];
                _lock.ExitReadLock();
                return rv;
            }
            set
            {
                _lock.EnterWriteLock();
                BaseDictionary[key] = value;
                _lock.ExitWriteLock();

            }
        }

        #endregion

        #region ICollection<KeyValuePair<TKey,TValue>> Members

        public void Add(KeyValuePair<TKey, TValue> item)
        {
            _lock.EnterWriteLock();
            BaseCollection.Add(item);
            _lock.ExitWriteLock ();
          
        }

        public void Clear()
        {
            _lock.EnterWriteLock();
            BaseCollection.Clear ();
            _lock.ExitWriteLock();
        }

        public bool Contains(KeyValuePair<TKey, TValue> item)
        {
            _lock.EnterReadLock ();
            var rv = BaseCollection.Contains(item);
            _lock.ExitReadLock ();
            return rv;

        }

        public void CopyTo(KeyValuePair<TKey, TValue>[] array, int arrayIndex)
        {
            _lock.EnterReadLock();
            BaseCollection.CopyTo(array, arrayIndex);
            _lock.ExitReadLock();
        }

        public int Count
        {
            get {
                _lock.EnterReadLock();
                var rv = BaseCollection.Count;
                _lock.ExitReadLock();
                return rv;
            }
        }

        public bool IsReadOnly
        {
            get
            {

                return BaseCollection.IsReadOnly;

            }
        }

        public bool Remove(KeyValuePair<TKey, TValue> item)
        {
            _lock.EnterWriteLock ();
            var rv = BaseCollection.Remove(item);
            _lock.ExitWriteLock();
            return rv;
        }

        #endregion

        #region IEnumerable<KeyValuePair<TKey,TValue>> Members

        public IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator()
        {
            return BaseDictionary.GetEnumerator();
        }

        #endregion

        #region IEnumerable Members

        IEnumerator IEnumerable.GetEnumerator()
        {
            return BaseDictionary.GetEnumerator();
        }

        #endregion
    }
}